/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author pipo
 */
package mainGame;

import controller.IconManager;
import java.awt.Dimension;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class FightManager  extends JFrame {
    
    private drawPane infoPanel;
    private JButton surrenderButton;
    private Player player;
    private Trainer enemy;
    private boolean isTrap;
    private Map map;
    private JFrame main;
    
    public FightManager(JFrame main, Map m , Player p, Trainer e, boolean isTrap)
    {
        super("Fight");
        controller.SoundManager.s1.stop();
        controller.SoundManager.s2.loop();
        this.main = main;
        this.player = p;
        this.isTrap = isTrap;
        this.enemy = e;
        this.map = m;
        this.showDialog(e);
        infoPanel = new drawPane();
        this.setContentPane(infoPanel);
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.pack();
        this.setPreferredSize(new Dimension(900,750));
        this.setResizable(false);
        
    }
    
    public void showDialog(Trainer e)
    {
        
        String s = e.getName();
        String message , message2;
        if(this.isTrap)
        {
            message = "You have encountered with the trap pokemon: " + this.enemy.getName() + "\nPrepare to Battle" ;
            message2 = "Trap Pokemon Encountered!";
            
        }
        else
        {
            message = "You have encountered with the enemy trainer: " + this.enemy.getName() + "\nPrepare to Battle" ;
            message2 ="Enemy Trainer Encountered!";
            
        }
        JOptionPane.showMessageDialog(this,
        message,
    message2,
    JOptionPane.WARNING_MESSAGE);
        
    }
    
    
    private class drawPane extends JPanel
    {

         private JButton surrenderButton;
         private InfoPanel info;
         private FightPanel fight;
        
         public drawPane()
         {
            this.setLayout(new BorderLayout());
            this.info = new InfoPanel();
            this.fight = new FightPanel();
            this.surrenderButton = new JButton("SURRENDER");
            this.surrenderButton.addActionListener(new SurrenderListener() );
            this.surrenderButton.setBackground(Color.YELLOW);
            this.add(surrenderButton , BorderLayout.PAGE_END);
            this.add(info , BorderLayout.PAGE_START);
            this.add(fight, BorderLayout.CENTER);
            this.setPreferredSize(new Dimension(900,750));

         }

 
         private class SurrenderListener implements ActionListener
         {
             
          public void actionPerformed(ActionEvent event) 
          {
              
              int dialogButton = JOptionPane.YES_NO_OPTION;
                if(JOptionPane.showConfirmDialog(null,
                "Are you sure to surrender this fight? This will cause you %50 percent of your current experience points.", 
                "Surrender",
                dialogButton)  == JOptionPane.YES_OPTION )
                {
                    player.reduceExperience();
                    player.refreshPokemons(4);
                    enemy.refreshPokemons(3);
                    controller.SoundManager.s2.stop();
                    controller.SoundManager.s1.loop();
                    main.setVisible(true);
                    FightManager.this.dispose();   
                }
              
               
          }
             
         }
    
    
    private class InfoPanel extends JPanel {
        
        private JButton tips;
        
        public InfoPanel()
                {
                    this.tips = new JButton("Tips");
                    this.tips.addActionListener(new TipsListener());
                    this.add(tips);
                    this.setPreferredSize(new Dimension(900,650));                    
                }
                
        private class TipsListener implements ActionListener
                {
            
                    public void actionPerformed(ActionEvent evt)
                    {
                                //Electric type good against Water, bad against Earth and Electric type; equal with fire
        //Fire type good against Earth, bad against water and fire; equal with electric
        //Water type good against Fire and bad against electric and water; equal with earth
        //Earth type good against electric and bad against Fire and Earth; equal with Water
                        String message = "Electic Type -> Good Against: Water  -  Bad Against: Earth and Electric  -  Equal with Fire\n"
                                + "Fire Type -> Good Against: Earth  -  Bad Against: Electric and Water  -  Equal with Electric\n" + 
                                "Water Type -> Good Against: Fire  -  Bad Against: Electric and Water  -  Equal with Earth\n" + 
                                "Earth Type -> Good Against: Electric  -  Bad Against: Fire and Earth  -  Equal with Water\n" + 
                                "Overall the Earth type Pokemons have the best defense against all types; and Electric type Pokemons have the worst defense against all types ";
                        JOptionPane.showMessageDialog(null, message, 
                        "Attack Info",
                        JOptionPane.WARNING_MESSAGE);
                    }
            
                }
        
         public void paintComponent(Graphics page)
           {
             super.paintComponent(page);
             Pokemon activeE = drawPane.this.fight.activeEnemyPokemon;
             Pokemon activeP = drawPane.this.fight.activePlayerPokemon;
             boolean isAttack = drawPane.this.fight.isAttack;
             drawPokemons(page, activeP , activeE , isAttack);
             int h = 350;
             String enemyMessage;
             if(!isTrap)
                 enemyMessage = "POKEMONS OF THE ENEMY TRAINER: ";
             else
                 enemyMessage = "TRAP POKEMON: "; 
             String plist = player.pokemonList();
             String elist = enemy.pokemonList();
             page.setFont(new Font("Arial" , Font.BOLD , 14));
             page.drawString("YOUR POKEMONS:", 20, 20 + h);
             this.splitAndDrawLines(page, plist, 20, 40 + h);
             int X = player.pokemonCount() * 20 + h + 60;
             page.setFont(new Font("Arial" , Font.BOLD , 14));
             page.drawString(enemyMessage + enemy.getName(), 20, X);
             this.splitAndDrawLines(page , elist , 20 , X + 20);
         }
         
         public void splitAndDrawLines(Graphics page , String s , int X , int Y)
         {
             page.setFont(new Font("Arial", Font.PLAIN , 12));
             String temp = "";
             int newX = X;
             int newY = Y;
             for(int i = 0 ; i < s.length() ; i++)
             {
                 if(s.charAt(i) != '\n')
                    temp += s.charAt(i);
                 if(s.charAt(i) == '\n' )
                 {
                   page.drawString(temp, newX, newY);
                   newX = newX;
                   newY = newY + 20;
                   temp = ""; 
                 
                }
            
            }
             
        }
         
         public void drawPokemons(Graphics page , Pokemon P , Pokemon E , boolean isAttack)
         {


             Image playerPokemon = IconManager.returnPokemonImage(P.getName());
             Image enemyPokemon = IconManager.returnPokemonImage(E.getName());
             Image attackImage = IconManager.attack.returnImage();
             
             page.drawImage(playerPokemon, 265, 30, -1 * playerPokemon.getWidth(null), playerPokemon.getHeight(null) , null);
             if(isAttack) page.drawImage(attackImage, 300, 30, null);
             page.drawImage(enemyPokemon, 650 , 30 , null);
             
         }
         
                           
    }
    
    private class FightPanel extends JPanel
    {
        
        private JButton attack1, attack2 , attack3 , attackInfo1 , attackInfo2 , attackInfo3;
        private JButton changePokemon;
        private JLabel enemyActivePName, playerActivePName;
        private boolean isAttack;
        private int playerPokemonIndex , enemyPokemonIndex;
        Pokemon activePlayerPokemon, activeEnemyPokemon;
        
        public FightPanel()
        {
            this.playerPokemonIndex = 0;
            this.enemyPokemonIndex = 0;
            this.isAttack = false;
            this.activePlayerPokemon = player.returnPokemon(0);
            this.activeEnemyPokemon = enemy.returnPokemon(0);
            this.setPreferredSize(new Dimension(900,100));
            this.setLayout(new GridLayout(3,3, 30 , 5));
            attack1 = new JButton("ATTACK 1");
            attack1.addActionListener(new AttackListener(1));
            attackInfo1 = new JButton("Info");
            attackInfo1.addActionListener(new AttackInfoListener(1));
            attack2 = new JButton("ATTACK 2");
            attack2.addActionListener(new AttackListener(2));
            attackInfo2 = new JButton("Info");
            attackInfo2.addActionListener(new AttackInfoListener(2));
            attack3 = new JButton("ATTACK 3");
            attack3.addActionListener(new AttackListener(3));
            attackInfo3 = new JButton("Info");
            attackInfo3.addActionListener(new AttackInfoListener(3));
            changePokemon = new JButton("Change Pokemons");
            changePokemon.addActionListener(new changePokemonsListener());
            enemyActivePName = new JLabel();
            playerActivePName = new JLabel();
            this.update();            
            this.add(playerActivePName);
            this.add(changePokemon);
            this.add(enemyActivePName);
            this.add(attack1);
            this.add(attack2);
            this.add(attack3);
            this.add(attackInfo1);
            this.add(attackInfo2);
            this.add(attackInfo3); 
            
        }
        
        public void update()
        {
            this.isAttack = false;
            if(player.pokemonCount() > 0)
            {
               this.activePlayerPokemon = player.returnPokemon(playerPokemonIndex );
               this.playerActivePName.setText("Player Active Pokemon: " + this.activePlayerPokemon.getName());

            }
            
            if(enemy.pokemonCount() > 0)
            {
                
            this.activeEnemyPokemon = enemy.returnPokemon(enemyPokemonIndex );   
            this.enemyActivePName.setText("Enemy Active Pokemon: " +this.activeEnemyPokemon.getName());
            
            }

            drawPane.this.info.repaint();
        }
        
        public void changeActivePokemon(Trainer t , int pOrE)
        {
          int index = (pOrE == 0) ? playerPokemonIndex : enemyPokemonIndex;  
          if(index >= (t.pokemonCount()-1) )
          {
              if(pOrE == 0)
                  playerPokemonIndex = 0;
              else
                  enemyPokemonIndex = 0;
          }
          else
          {
              if(pOrE == 0)
                  playerPokemonIndex++;
              else
                  enemyPokemonIndex++;
          }
          
         if((pOrE == 0 && player.pokemonCount() > 0) || (pOrE != 0 && enemy.pokemonCount() > 0 ) ) 
             update();
                    
        }
        
        private class changePokemonsListener implements ActionListener
        {
            
            public void actionPerformed(ActionEvent evt)
            {
                changeActivePokemon(player , 0);

            }
            
            
        }

        private class AttackInfoListener implements ActionListener
        {
            
            private int index;
            
            public AttackInfoListener(int index)
            {
                this.index = index -1;
    
            }
            
            public void actionPerformed(ActionEvent evt)
            {
                
                String message = "Attack Name: " + activePlayerPokemon.getAttackName(index) + "\n" + "Attack Properties: " + activePlayerPokemon.getAttackDescr(index);
                
                JOptionPane.showMessageDialog(null, message, 
                "Attack Info",
                JOptionPane.WARNING_MESSAGE);
                
            }
            
            
            
        }
        
        private class AttackListener implements ActionListener
        {
            private int index;
            
            public AttackListener(int index)
            {
                this.index = index;
            }
           
            @Override
            public void actionPerformed(ActionEvent evt)
            {
                playerHit();
                
            }
            
            public void playerHit()
            {
                FightPanel.this.isAttack = true;
                int damage = activePlayerPokemon.calculateOverallDamage(activeEnemyPokemon, index);
                activeEnemyPokemon.reduceHitPoints(damage);
                boolean dead = activeEnemyPokemon.isPokemonDead();
                infoPanel.repaint();
                String message;
                message = "You hit " +damage + " damage to enemy Pokemon " + activeEnemyPokemon.getName() + " with your " + 
                            activePlayerPokemon.getName() + " using " + activePlayerPokemon.getAttackName(index-1);
                JOptionPane.showMessageDialog(null, message, 
                "Successful Attack",
                JOptionPane.WARNING_MESSAGE);
                if(dead)
                {
                    PokemonKilledMessage();
                    player.addScore(activeEnemyPokemon.calculateScore());
                    activePlayerPokemon.addExperience(activeEnemyPokemon.expAmountWhenKilled());
                    calculateLevelUp();
                    enemy.releasePokemon(enemyPokemonIndex);
                    infoPanel.repaint();

                
                try {
                    Thread.sleep(350);
                } catch (InterruptedException ex) {
                    Logger.getLogger(FightManager.class.getName()).log(Level.SEVERE, null, ex);
                }
                    if(enemy.isAllPokemonsDead())
                    {
                        player.addScore(50);
                        JOptionPane.showMessageDialog(null, "You have defeated the enemy: " +enemy.getName(), 
                        "VICTORY",
                        JOptionPane.WARNING_MESSAGE);
                        map.deleteEnemyTrainer(enemy,isTrap);
                        controller.SoundManager.s2.stop();
                        controller.SoundManager.s1.loop();
                        main.setVisible(true);
                        player.refreshPokemons(3);
                        FightManager.this.dispose();   
                    }
                    else
                    {
                        changeActivePokemon(enemy, 1);
                        update();   
                        this.enemyHit();
                    }

                }

                
                else        
                {
                    update();
                    this.enemyHit();
                }
                

                
            }
            
            
            public void enemyHit()
            {
                FightPanel.this.isAttack = true;
                try {
                    Thread.sleep(750);
                } catch (InterruptedException ex) {
                    Logger.getLogger(FightManager.class.getName()).log(Level.SEVERE, null, ex);
                }
                
                Random generator = new Random();
                int attack = generator.nextInt(3);
                int damage = activeEnemyPokemon.calculateOverallDamage(activePlayerPokemon, attack);
                activePlayerPokemon.reduceHitPoints(damage);
                infoPanel.repaint();
                JOptionPane.showMessageDialog(null,
                "Enemy hit  " +damage + " damage to your Pokemon " + activePlayerPokemon.getName() + " with his " + activeEnemyPokemon.getName() 
                + " using " + activeEnemyPokemon.getAttackName(attack), 
                "HIT",
                JOptionPane.WARNING_MESSAGE);
                
                if(activePlayerPokemon.isPokemonDead())
                {
                    
                    pokemonDead();
                    int experience = activePlayerPokemon.expAmountWhenKilled();
                    activeEnemyPokemon.addExperience(experience);
                    enemy.levelUp(enemyPokemonIndex);
                    player.releasePokemon(playerPokemonIndex);
                    if(player.isAllPokemonsDead())
                    {
                        infoPanel.repaint();
                        gameOver();
                        main.dispose();
                        FightManager.this.dispose();
                        
                        
                    }
                    
                    else
                    {
                        activePlayerPokemon = player.returnPokemon(0);
                        playerPokemonIndex = 0;
                        update();              
                    }

                    
                    
                }
                 if(activeEnemyPokemon.getPercent() <= 40  && enemy.pokemonCount() >  1)
                        changeActivePokemon(enemy, 1);
                 
                 
                infoPanel.repaint();
                update();
              
            }
            
            public void pokemonDead()
            {
                String message = "Your Pokemon " +activePlayerPokemon.getName() + " is dead, so it is released from your inventory. ";
                JOptionPane.showMessageDialog(null, message,
                "Pokemon died!",
                JOptionPane.WARNING_MESSAGE);
            }
            
            public void gameOver()
            {
                
                controller.SoundManager.s2.stop();
                controller.SoundManager.s3.loop();
                String message = "All of your pokemons have died, Game Over!";
                JOptionPane.showMessageDialog(null, message,
                "GAME OVER!",
                JOptionPane.WARNING_MESSAGE);
                FightManager.this.dispose();
                new menus.GameOver(player).setVisible(true);
                
            }
        }
        
        public void calculateLevelUp()
        {
            if(player.levelUp(playerPokemonIndex))
            {
                showLevelUpDialog();
            }

       }
        
        public void showLevelUpDialog()
        {
            JOptionPane.showMessageDialog(null,
            "Your Pokemon " +activePlayerPokemon.getName() + " has leveled up!",
            "LEVEL UP",
            JOptionPane.WARNING_MESSAGE);
            
        }
        
        public void PokemonKilledMessage()
        {             
                int dialogButton = JOptionPane.YES_NO_OPTION;
                boolean inventoryFull = player.pokemonCount() >= 3;
                String message = "You have defeated the enemy Pokemon " + activeEnemyPokemon.getName() + ". Do you wish to add this Pokemon to your inventory?";
                if(inventoryFull) message += "\n (Your inventory is full , you will need to release a Pokemon if you want to add another one)";
                if(JOptionPane.showConfirmDialog(null,
                message, 
                "Enemy Pokemon has been defeated.",
                dialogButton)  == JOptionPane.YES_OPTION )
                {
                    activeEnemyPokemon.refresh(4);
                    if(inventoryFull)
                    {
                        boolean release = PokemonFullMessage();
                        if(release)
                        {
                            player.addPokemon(activeEnemyPokemon);
                            infoPanel.repaint();
                        }
                        
                    }
                    else
                    {
                      player.addPokemon(activeEnemyPokemon);        
                      infoPanel.repaint();
                    }
                }
                  
            
            
        }
        
        public boolean PokemonFullMessage()
        {
            
                Object[] possibilities  = new Object[player.pokemonCount()+1];
                
                for(int i = 0 ; i < player.pokemonCount() ; i++)
                {
                    
                    possibilities[i] = "" + (i+1) + ": " + player.returnPokemon(i).getName();
                }
                possibilities[player.pokemonCount()] = "Cancel";
                
                String s = (String)JOptionPane.showInputDialog(
                    null,
                    "Choose the pokemon to release: ",
                    "Release Pokemon",
                    JOptionPane.PLAIN_MESSAGE,
                    null,
                    possibilities,
                    "NONE");
                
                if ((s != null) && (s.length() > 0) && (!s.equals("Cancel")) && (!s.equals("NONE")))
                {
                    
                    int index = Character.getNumericValue(s.charAt(0));
                    if(index > 0)
                    {
                        player.releasePokemon(index-1);
                        return true;
                    }
                    
                
                }
                return false;
        }
        
                       
    }
  }

}
